package com.scheduling.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scheduling.common.exception.BusinessException;
import com.scheduling.product.dto.OperationDTO;
import com.scheduling.product.dto.ProcessRouteDTO;
import com.scheduling.product.entity.ProcessRoute;
import com.scheduling.product.entity.Product;
import com.scheduling.product.mapper.ProcessRouteMapper;
import com.scheduling.product.mapper.ProductMapper;
import com.scheduling.product.service.OperationService;
import com.scheduling.product.service.ProcessRouteService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 工艺路线业务层实现类
 *
 * @author 开发团队
 * @since 2025-05-29
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProcessRouteServiceImpl extends ServiceImpl<ProcessRouteMapper, ProcessRoute> implements ProcessRouteService {

    private final ProcessRouteMapper processRouteMapper;
    private final ProductMapper productMapper;
    private final OperationService operationService;

    @Override
    public ProcessRouteDTO getRouteByProductId(String productId) {
        log.info("根据产品ID查询工艺路线：{}", productId);

        if (StrUtil.isBlank(productId)) {
            throw new BusinessException("产品ID不能为空");
        }

        // 查询工艺路线
        ProcessRoute processRoute = processRouteMapper.selectByProductId(productId);
        if (processRoute == null) {
            return null;
        }

        // 转换为DTO并查询工序列表
        ProcessRouteDTO routeDTO = new ProcessRouteDTO();
        BeanUtil.copyProperties(processRoute, routeDTO);

        // 查询产品名称
        Product product = productMapper.selectById(productId);
        if (product != null) {
            routeDTO.setProductName(product.getProductName());
        }

        // 查询工序列表
        List<OperationDTO> operations = operationService.getOperationsByRouteId(processRoute.getRouteId());
        routeDTO.setOperations(operations);

        return routeDTO;
    }

    @Override
    public ProcessRouteDTO getRouteById(String routeId) {
        log.info("根据ID查询工艺路线：{}", routeId);

        if (StrUtil.isBlank(routeId)) {
            throw new BusinessException("工艺路线ID不能为空");
        }

        ProcessRoute processRoute = processRouteMapper.selectById(routeId);
        if (processRoute == null) {
            throw new BusinessException("工艺路线不存在");
        }

        // 转换为DTO
        ProcessRouteDTO routeDTO = new ProcessRouteDTO();
        BeanUtil.copyProperties(processRoute, routeDTO);

        // 查询产品名称
        Product product = productMapper.selectById(processRoute.getProductId());
        if (product != null) {
            routeDTO.setProductName(product.getProductName());
        }

        // 查询工序列表
        List<OperationDTO> operations = operationService.getOperationsByRouteId(routeId);
        routeDTO.setOperations(operations);

        return routeDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createRoute(ProcessRouteDTO routeDTO) {
        log.info("创建工艺路线：{}", routeDTO);

        // 验证产品是否存在
        Product product = productMapper.selectById(routeDTO.getProductId());
        if (product == null) {
            throw new BusinessException("产品不存在");
        }

        // 检查产品是否已有工艺路线
        if (checkProductRouteExists(routeDTO.getProductId(), null)) {
            throw new BusinessException("该产品已有工艺路线，一个产品只能有一条工艺路线");
        }

        ProcessRoute processRoute = new ProcessRoute();
        BeanUtil.copyProperties(routeDTO, processRoute);

        boolean result = save(processRoute);
        if (result) {
            log.info("创建工艺路线成功，工艺路线ID：{}", processRoute.getRouteId());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRoute(ProcessRouteDTO routeDTO) {
        log.info("更新工艺路线：{}", routeDTO);

        if (StrUtil.isBlank(routeDTO.getRouteId())) {
            throw new BusinessException("工艺路线ID不能为空");
        }

        // 检查工艺路线是否存在
        ProcessRoute existRoute = processRouteMapper.selectById(routeDTO.getRouteId());
        if (existRoute == null) {
            throw new BusinessException("工艺路线不存在");
        }

        // 验证产品是否存在
        Product product = productMapper.selectById(routeDTO.getProductId());
        if (product == null) {
            throw new BusinessException("产品不存在");
        }

        // 检查产品是否已有其他工艺路线
        if (checkProductRouteExists(routeDTO.getProductId(), routeDTO.getRouteId())) {
            throw new BusinessException("该产品已有其他工艺路线");
        }

        ProcessRoute processRoute = new ProcessRoute();
        BeanUtil.copyProperties(routeDTO, processRoute);

        boolean result = updateById(processRoute);
        if (result) {
            log.info("更新工艺路线成功，工艺路线ID：{}", processRoute.getRouteId());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRoute(String routeId) {
        log.info("删除工艺路线：{}", routeId);

        if (StrUtil.isBlank(routeId)) {
            throw new BusinessException("工艺路线ID不能为空");
        }

        // 检查工艺路线是否存在
        ProcessRoute processRoute = processRouteMapper.selectById(routeId);
        if (processRoute == null) {
            throw new BusinessException("工艺路线不存在");
        }


        // 删除工艺路线下的所有工序
        operationService.deleteOperationsByRouteId(routeId);

        boolean result = removeById(routeId);
        if (result) {
            log.info("删除工艺路线成功，工艺路线ID：{}", routeId);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean copyRoute(String sourceRouteId, String targetProductId, String routeName) {
        log.info("复制工艺路线，源工艺路线：{}，目标产品：{}，新名称：{}", sourceRouteId, targetProductId, routeName);

        if (StrUtil.isBlank(sourceRouteId) || StrUtil.isBlank(targetProductId) || StrUtil.isBlank(routeName)) {
            throw new BusinessException("参数不能为空");
        }

        // 检查源工艺路线是否存在
        ProcessRoute sourceRoute = processRouteMapper.selectById(sourceRouteId);
        if (sourceRoute == null) {
            throw new BusinessException("源工艺路线不存在");
        }

        // 验证目标产品是否存在
        Product targetProduct = productMapper.selectById(targetProductId);
        if (targetProduct == null) {
            throw new BusinessException("目标产品不存在");
        }

        // 检查目标产品是否已有工艺路线
        if (checkProductRouteExists(targetProductId, null)) {
            throw new BusinessException("目标产品已有工艺路线");
        }

        // 创建新的工艺路线
        ProcessRoute newRoute = new ProcessRoute();
        newRoute.setProductId(targetProductId);
        newRoute.setRouteName(routeName);

        boolean routeResult = save(newRoute);
        if (!routeResult) {
            throw new BusinessException("复制工艺路线失败");
        }

        // 复制工序
        List<OperationDTO> sourceOperations = operationService.getOperationsByRouteId(sourceRouteId);
        for (OperationDTO sourceOperation : sourceOperations) {
            sourceOperation.setOperationId(null); // 清空ID，让系统自动生成
            sourceOperation.setRouteId(newRoute.getRouteId()); // 设置新的工艺路线ID
            operationService.addOperation(sourceOperation);
        }

        log.info("复制工艺路线成功，新工艺路线ID：{}", newRoute.getRouteId());
        return true;
    }

    @Override
    public boolean checkProductRouteExists(String productId, String excludeId) {
        if (StrUtil.isBlank(productId)) {
            return false;
        }
        Integer count = processRouteMapper.checkProductRouteExists(productId, excludeId);
        return count != null && count > 0;
    }
} 